package com.megvii.koala.update;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.megvii.corelib.base.MegviiActivity;
import com.megvii.corelib.base.ProgressBarHolder;
import com.megvii.corelib.net.Callback;
import com.megvii.corelib.update.UpdateManager;
import com.megvii.corelib.update.activity.UpdateActivity;
import com.megvii.corelib.update.param.UpdateActivityParam;
import com.megvii.corelib.update.service.UpdateService;
import com.megvii.corelib.update.task.UpdateDialog;
import com.megvii.corelib.util.AlertDialogUtil;
import com.megvii.corelib.util.AppUtil;
import com.megvii.corelib.util.MegviiToast;
import com.megvii.koala.R;
import com.megvii.koala.constance.ErrorCode;
import com.megvii.koala.net.NetAPI;
import com.megvii.koala.net.update.AppUpdateResponse;

/**
 * Created by linyue on 16/3/8.
 */
public class AppUpdateChecker
        implements Response.ErrorListener, UpdateDialog.UpdateDialogListener, UpdateManager.UpdateManagerListener {
    private boolean passedChecking = false;

    private boolean updating = false;

    private Activity activity;

    /**
     * 如果已经是最新版本了，是否要弹框提示
     */
    private boolean showAlertIfIsLatestVersion;

    private ServiceConnection serviceConnection;

    private UpdateManager updateManager;

    private ProgressBarHolder progressBarHolder;

    private String fileNamePrefix;

    private String currentVer;

    private UpdateDialog updateDialog;

    private AppUpdateResponse.AppUpdateData data;

    private AppUpdateCheckerListener listener;

    public AppUpdateChecker(Activity activity, ProgressBarHolder progressBarHolder,
                            String fileNamePrefix) {
        super();
        this.progressBarHolder = progressBarHolder;
        this.activity = activity;
        this.fileNamePrefix = fileNamePrefix;
        updateDialog = new UpdateDialog();
    }

    public static String getApkFileName(String prefix, String version) {
        return prefix + "-" + version + ".apk";
    }

    public void release() {
        if (updateManager != null) {
            updateManager.unregisterListener(this);
        }
        if (serviceConnection != null) {
            activity.unbindService(serviceConnection);
        }
    }

    public void checkUpdate(final String type, final String currentVersion,
                            final boolean showAlertIfIsLatestVersion) {
        this.showAlertIfIsLatestVersion = showAlertIfIsLatestVersion;
        updating = true;
        currentVer = currentVersion;
        progressBarHolder.showProgressBar();
        serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                UpdateService.UpdateServiceBinder binder = (UpdateService.UpdateServiceBinder) service;
                updateManager = binder.updateManager;
                updateManager.registerListener(AppUpdateChecker.this);
                if (updateManager.isDownloading()) {
                    progressBarHolder.hideProgressBar();
                    startUpdateActivity(updateManager.getDownloadingUrl(),
                            updateManager.getDownloadingAPKName(), currentVersion, false);
                } else {
                    NetAPI.requestAppUpdate(type, currentVersion, AppUpdateChecker.this,
                            AppUpdateChecker.this);
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                updateManager.unregisterListener(AppUpdateChecker.this);
            }
        };
        activity.bindService(new Intent(activity, UpdateService.class), serviceConnection,
                Context.BIND_AUTO_CREATE);
    }

    public boolean isPassedChecking() {
        return passedChecking;
    }

    public boolean isUpdating() {
        return updating;
    }

    public void startUpdateActivity(String url, String apkFileName, String currentVersion,
                                    boolean forceUpdate) {
        Intent intent = new Intent(activity, UpdateActivity.class);
        intent.putExtra(MegviiActivity.KEY_ACTIVITY_PARAM,
                new UpdateActivityParam(R.layout.update_layout, url, apkFileName, currentVersion,
                        forceUpdate));
        activity.startActivity(intent);
        activity.overridePendingTransition(R.anim.fade_in, 0);
    }

    @Callback(clazz = AppUpdateResponse.class)
    public void onAppUpdateResponse(AppUpdateResponse response) {
        progressBarHolder.hideProgressBar();
        if (response.code == ErrorCode.NO_ERROR) {
            data = response.data;
            //版本号不一样就更新 TODO 需要改为判断服务器版本是否比本地高!data.version.equals(AppUtil.getAppVersion(activity))
            if (data.version != null && checkNeedUpdate(currentVer,data.version,"\\.")) {
                updateDialog.show(activity, response.data.version, response.data.description,
                        response.data.force, this);
            } else {
                if (showAlertIfIsLatestVersion) {
                    AlertDialogUtil.showMessage(activity, "已经更新到最新版本",
                            new AlertDialogUtil.AlertDialogListener() {
                                @Override
                                public void onAlertDialogClose() {
                                    updating = false;
                                    passedChecking = true;
                                    if (listener != null) {
                                        listener.onNoUpdate();
                                    }
                                }
                            });
                } else {
                    updating = false;
                    passedChecking = true;
                    if (listener != null) {
                        listener.onNoUpdate();
                    }
                }
            }
        } else {
            MegviiToast.showToast(activity, "更新请求错误：" + ErrorCode.getDescription(response.code));
        }
    }

    @Override
    public void onErrorResponse(VolleyError error) {
        progressBarHolder.hideProgressBar();
        MegviiToast.showToast(activity, "无法连接更新服务器，请重试");
    }

    @Override
    public void onClickUpdate() {
        updating = true;
        String apkFileName = getApkFileName(fileNamePrefix, data.version);
        //"https://dl.google.com/dl/android/studio/install/1.5.0.4/android-studio-ide-141.2422023-windows.exe"
        startUpdateActivity(data.url, apkFileName, data.version, data.force);
        if (!data.force) {
            passedChecking = true;
        }
        if (listener != null) {
            listener.onConfirmedUpdate();
        }
    }

    @Override
    public void onClickCancel() {
        if (data.force) {
            AppUtil.FakeExitApp(activity);
        } else {
            passedChecking = true;
        }
        if (listener != null) {
            listener.onRejectedUpdate();
        }
    }

    //UpdateManager callback start
    @Override
    public void onGetSpaceNeeded(String urlString, String fileName, int size) {

    }

    @Override
    public void onDownloadStart() {

    }

    @Override
    public void onDownloadProgress(int progress) {

    }

    @Override
    public void onDownloadCompleted(String fileName) {
        updating = false;
        passedChecking = true;
    }

    @Override
    public void onDownloadError(String url, String fileName, int errorCode) {

    }

    @Override
    public void onDownloadInterrupt() {

    }
    //UpdateManager callbacks end

    public void setListener(AppUpdateCheckerListener listener) {
        this.listener = listener;
    }

    public interface AppUpdateCheckerListener {
        public void onConfirmedUpdate();

        public void onRejectedUpdate();

        /**
         * 当检查到已经是最新版本
         */
        public void onNoUpdate();
    }

    /**
     * 检测是否需要更新
     * @param oldVersion
     * @param newVersion
     * @param spliter
     * @return
     */
    private boolean checkNeedUpdate(String oldVersion, String newVersion, String spliter) {
        String[] oldVers = oldVersion.split(spliter);
        String[] newVers = newVersion.split(spliter);
        int length = 0;
        boolean isNewverLong = false;
        if (oldVers.length >= newVers.length) {
            length = newVers.length;
        } else {
            isNewverLong = true;
            length = oldVers.length;
        }
        for (int i = 0; i < length; i++) {
            if (Integer.parseInt(newVers[i]) > Integer.parseInt(oldVers[i])) {
                return true;
            }
        }
        return isNewverLong;
    }
}
